﻿using MiniFox.Infrastructure.Attributes;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace MiniFox.Infrastructure
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class TreeGroupBase<D> : ITreeGroup
    {
        private object _groupId;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="groupId"></param>
        public TreeGroupBase(object groupId)
        {
            this._groupId = groupId;
        }
        /// <summary>
        /// 组ID
        /// </summary>
        public object GroupID
        {
            get
            {
                return _groupId;
            }
        }
        /// <summary>
        /// 节点唯一ID属性（字段）名
        /// </summary>
        public string NodeKey
        {
            get;
            protected set;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <returns></returns>
        protected abstract object GetUniqueID(D flatDataItem);

        /// <summary>
        /// 节点父级ID属性（字段）名
        /// </summary>
        public string SuperKey
        {
            get;
            protected set;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <returns></returns>
        protected abstract object GetSuperID(D flatDataItem);

        /// <summary>
        /// 节点排序属性（字段）名
        /// </summary>
        public string SortKey
        {
            get;
            protected set;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <returns></returns>
        protected abstract object GetSortValue(D flatDataItem);

        ITreeNode _rootNode;
        /// <summary>
        /// 
        /// </summary>
        public virtual ITreeNode Tree
        {
            get
            {
                if (_rootNode == null)
                {
                    _rootNode = CreateTree(this.RootData, 0);
                }
                return _rootNode;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        protected abstract D RootData { get; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="nodeId"></param>
        /// <returns></returns>
        public abstract ITreeNode CreateTreeByNodeID(object nodeId);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <returns></returns>
        protected abstract IEnumerable<D> GetChildren(D flatDataItem);
        /// <summary>
        /// 创建指定节点的树
        /// </summary>
        /// <param name="flatDataItem">根节点数据</param>
        /// <param name="level"></param>
        /// <returns></returns>
        public ITreeNode CreateTree(D flatDataItem, int level)
        {
            //递归映射数据到树节点
            var treeNode = RecursionMapping(flatDataItem, level);
            return treeNode;
        }
        /// <summary>
        /// 递归算法封装
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <param name="level"></param>
        protected internal ITreeNode RecursionMapping(D flatDataItem, int level)
        {
            var treeNode = CreateTreeNode(flatDataItem, level);
            if (treeNode == null)
                return null;
            var childrenData = GetChildren(flatDataItem);
            if (childrenData != null || childrenData.Count() > 0)
            {
                IList<ITreeNode> children = new List<ITreeNode>();
                foreach (D childData in childrenData)
                {
                    var childNode = RecursionMapping(childData, level + 1);
                    if (childNode == null)
                        continue;
                    children.Add(childNode);
                }

                if (children.Count > 0)
                    treeNode.Children = children.OrderBy(n => n.Ordinal);
            }
            return treeNode;
        }
        /// <summary>
        /// 创建树节点
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        protected virtual ITreeNode CreateTreeNode(D flatDataItem, int level)
        {
            if (flatDataItem == null)
                return null;
            var nodeData = Mapping(flatDataItem);
            if (nodeData == null)
                return null;
            var treeNode = new TreeNode(nodeData);
            treeNode.ID = this.GetUniqueID(flatDataItem);
            treeNode.Level = level;
            if (this.GetSortValue(flatDataItem) is int ordinal)
                treeNode.Ordinal = ordinal;
            return treeNode;
        }
        /// <summary>
        /// 扁平数据映射，默认直接返回，可重写为返回自定义对象
        /// </summary>
        /// <param name="flatDataItem"></param>
        /// <returns></returns>
        protected virtual object Mapping(D flatDataItem)
        {
            return flatDataItem;
        }
    }
}